﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ConsoleTesrt.LINQTest
{
    public class LinqXML
    {

        static void Mainddd4(string[] ar)
        {
            //todo:LINQ操作XML
            //XDocument         创建XML文档
            //XDeclaration       创建XML中的声明
            //XElement             创建XML中的元素
            //XAttribute            创建XML中元素的属性
            //XComment           创建XML中的注释
            //TODO:读取xml
            string filePath1 = @"C:\Users\Alan\Desktop\AvalonSolution\ConsoleTesrt\LINQTest\XMLData.xml";
            XElement doc2 = XElement.Load(filePath1);
            Console.WriteLine(doc2.ToString());
            XDocument doc3 = XDocument.Load(filePath1);
            //todo:查找根元素
            Console.WriteLine("根元素：" + doc3.Root.Name);
            //todo:查找指定名称的元素 PS:Attribute
            Console.WriteLine("查找指定IDWEI1的元素");
            var elements1 = from xml in doc2.Elements("Product")
                            where xml.Attribute("ID").Value == "1"
                            select xml;
            foreach (var xe in elements1)
            {
                Console.WriteLine(xe.Name.LocalName + ":" + xe.Attribute("ID").Value);
            }
            //todo:查找指定属性的元素
            var elements2 = from xml in doc2.Elements("Product") //获得所有的Product节点
                            select new
                            {
                                编号 = xml.Element("ID").Value,
                                产品编号 = xml.Element("ProductCode").Value,
                                产品名称 = xml.Element("ProductName").Value,
                                产品单价 = xml.Element("ProductUnitPrice").Value,
                                产品类型ID = xml.Element("ProductTypeID").Value,
                                产品描述 = xml.Element("ProductDescription").Value
                            };
            foreach (var item in elements2)
            {
                Console.WriteLine("产品名称\t" + item.产品名称);
            }
            string ProductID = "2";
            //todo:查找指定属性根据Attribute的元素
            var elements3 = from xml in doc2.Elements("Product")
                            where xml.Attribute("ID").Value == ProductID
                            select new
                            {
                                编号 = xml.Element("ID").Value,
                                产品编号 = xml.Element("ProductCode").Value,
                                产品名称 = xml.Element("ProductName").Value,
                                产品单价 = xml.Element("ProductUnitPrice").Value,
                                产品类型ID = xml.Element("ProductTypeID").Value,
                                产品描述 = xml.Element("ProductDescription").Value
                            };
            foreach (var item in elements3)
            {
                Console.WriteLine("ID为" + ProductID + "的产品名称为" + item.产品名称);
            }
            //TODO:访问指定元素的所有属性
            //XElement.FirstAttribute：获取此元素的第一个属性
            //XElement.NextAttribute:  获取父元素的下一个属性
            XAttribute firstAttr = doc2.FirstAttribute;
            //如果第一个不为空，我们继续查找下一个属性
            if (firstAttr != null)
            {
                Console.WriteLine(firstAttr.Name.LocalName + "：" + firstAttr.Value);
                XAttribute nextAttr = firstAttr.NextAttribute;
                while (nextAttr != null)
                {
                    Console.WriteLine(nextAttr.Name.LocalName + "：" + nextAttr.Value);
                    nextAttr = nextAttr.NextAttribute;
                }
            }
            //TODO: 查找XML中指定名称的元素
            //XContainer类(XDocument的父类)的Descendants(XName name)
            //Descendants方法用于按文档顺序返回此文档或元素的经过筛选的自带元素的集合，集合中只包括具有匹配XName的元素
            IEnumerable<XElement> elements4 = from xml in doc2.Descendants("ProductName")
                                              select xml;
            foreach (var item in elements4)
            {
                Console.WriteLine(item.Name + "：" + item.Value);
            }
            Console.WriteLine("********************************************************************************");
            //TODO:遍历指定节点下的所有对象
            IEnumerable<XNode> nodes = doc2.Elements("Product").Nodes();
            foreach (XNode item in nodes)
            {
                Console.WriteLine(item.ToString());
            }
            //TODO:使用OfType<T> 筛选返回指定节点下的T
            //返回注释XComment
            Console.WriteLine("************************************************");
            IEnumerable<XComment> cmts = doc2.Elements("Product").Elements("ProductCode").Nodes().OfType<XComment>();
            foreach (XComment item in cmts)
            {
                Console.WriteLine(item.ToString());
            }
            //TODO:访问指定节点的父元素
            string proname = "相宜本草男士专用洗面奶";
            //XElement elements6 = doc2.Descendants("ProductName")
            //                     .Where(itm => itm.Value == (proname))
            //                     .First();
            ////获得它上面的父元素
            //XElement xex = elements6.Parent;
            //Console.WriteLine("《" + proname + "》对应的编码为" + xex.Element("ProductCode").Value);
            //todo:按元素名称排序
            var xx = from xml in doc2.Elements("Product")
                     orderby xml.Element("ProductName").Value
                     select new
                     {
                         产品名称 = xml.Element("ProductName").Value,
                         产品单价 = xml.Element("ProductUnitPrice").Value
                     };
            foreach (var item in xx)
            {
                Console.Write(item.产品名称 + "：" + item.产品单价 + "元");
            }
            //todo:使用Ancestors
            Console.WriteLine("使用Ancestors获取父级元素");
            IEnumerable<XElement> elements8 = from xml in doc2.Descendants("ProductName")
                                              select xml;
            Console.WriteLine("原来的元素");
            foreach (XElement item in elements8)
            {
                Console.WriteLine(item.Name + "：" + item.Value);
            }
            //显示每个元素的父元素
            Console.WriteLine("现在的父元素");
            foreach (XElement item in elements8.Ancestors())
            {
                Console.WriteLine(item.Name + "：" + item.Value);
            }
            //todo:返回元素集合中每个元素的所有属性，使用Attributes的使用
            foreach (XAttribute item in elements8.Attributes())
            {
                Console.WriteLine(item.Name + ":::::::：:::::::::" + item.Value);
            }
            //todo:返回节点集合中每个节点的所有下级节点
            Console.WriteLine("返回节点集合中每个节点的所有下级节点");
            foreach (XNode item in elements8.DescendantNodes())
            {
                Console.WriteLine(item.ToString());
            }
            //todo:LINQTOXML操作基础
            XElement newe = new XElement("Product", new XAttribute("ID", "3"),
                             new XElement("ID", "3", new XComment("编号"), new XAttribute("type", "int")),
                             new XElement("ProductCode", "DBTNT", new XComment("产品编号"), new XAttribute("type", "nvarchar(50)")),
                             new XElement("ProductName", "大白兔奶糖", new XComment("产品名称"), new XAttribute("type", "nvarchar(50)")),
                             new XElement("ProductUnitPrice", "19.90", new XComment("产品单价"), new XAttribute("type", "decimal(18,2)")),
                             new XElement("ProductTypeID", "2", new XComment("产品类型"), new XAttribute("type", "smallint"),
                                     new XAttribute("ForeignTable", "ProductType"),
                                     new XAttribute("ForeignTableColumn", "ID")
                             ),
                             new XElement("ProductDescription", "浓浓的奶香", new XComment("产品描述"), new XAttribute("type", "nvarchar(200)"))
               );
            doc2.Add(newe);
            doc2.Save(filePath1);
            Console.WriteLine("添加元素成功！");
            //TODO:修改XML元素和属性
            IEnumerable<XElement> elements9 = from xml in doc2.Elements("Product")
                                              where xml.Element("ID").Value == "1"
                                              && xml.Element("ProductTypeID").Value == "1"
                                              select xml;
            if (elements9.Count() > 0)
            {
                XElement one = elements9.FirstOrDefault();
                one.SetElementValue("ProductName", "第一个产品");
                one.SetAttributeValue("ID", "7");
            }
            doc2.Save(filePath1);
            Console.WriteLine("修改元素属性和节点成功！");
            //TODO: 替换指定节点下的所有元素
            IEnumerable<XElement> elements10 = from xml in doc2.Elements("Product")
                                               where xml.Element("ID").Value == "1" && xml.Element("ProductTypeID").Value == "1"
                                               select xml;
            if (elements10.Count() > 0)
            {
                XElement one = elements10.First();
                one.ReplaceAll(
                    new XAttribute("ID", "1"),
                    new XElement("ProductName", "相宜本草男士专用洗面奶", new XComment("产品名称"), new XAttribute("type", "nvarchar(50)")),
                    new XElement("ProductTypeID", "2")
                    );
            }
            doc2.Save(filePath1);
            Console.WriteLine("替换元素属性和节点成功！");
            //TODO:删除XML中的元素
            //使用XElement.Remove()方法，可以删除节点
            //TODO:合计XML元素值
            IEnumerable<XElement> elements11 = from ee in doc2.Elements("Product")
                                               select ee;
            decimal sums = elements11.Sum(i => Convert.ToDecimal(i.Element("ProductUnitPrice").Value));
            Console.WriteLine("累加后的产品总价为" + sums);
            //TODO:LINQTOXML属性操作
            IEnumerable<XElement> elements12 = from xml in doc2.Elements("Product")
                                               where xml.Attribute("ID").Value == "1"
                                               select xml;
            XAttribute xa = new XAttribute("Increaments", "每次增长的值的大小");
            if (elements12.Count() > 0)
            {
                XElement xles = elements12.FirstOrDefault();
                //xles.Add(xa);ps：添加一次就够了
            }
            doc2.Save(filePath1);
            Console.WriteLine("添加元素属性成功！");
            //TODO:修改XML属性
            if (elements12.Count() > 0)
            {
                XElement xles = elements12.FirstOrDefault();
                xles.Attribute("Increaments").Value = "每次增长的值的大小已经被我修改了";
            }
            doc2.Save(filePath1);
            Console.WriteLine("修改元素属性成功！");
            //todo:删除,同元素一样,获得后XAttribute后.Remove()就可以删除
            //todo:删除一个元素上的所有属性，获得XElement后.RemoveAttributes()就可以删除一个元素上的所有属性
            //todo:其他操作（添加注释到xml文件）
            IEnumerable<XElement> elements13 = from xml in doc2.Elements("Product")
                                               where xml.Attribute("ID").Value == "1"
                                               select xml;
            //添加注释到xml文件
            if (elements13.Count() > 0)
            {
                XElement xelements = elements13.FirstOrDefault();
                XComment comx = new XComment("这是我测试的注释2016年6月29日1:10:28");
                xelements.AddFirst(comx);
            }
            doc2.Save(filePath1);
            Console.WriteLine("添加注释到xml成功！");
            //todo:添加声明到XML文件中
            XDocument doc5 = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XElement("People", "亟待解决")
                );
            doc5.Save(@"C:\Users\Alan\Desktop\AvalonSolution\ConsoleTesrt\LINQTest\XMLData2.xml");
            Console.WriteLine("添加了一个声明的XML创建成功");
            //todo:添加文档类型到XML文件中（XDocumentType）
            XDocument doc6 = new XDocument(
                new XDocumentType("People", null, "People.dtd", null),
                new XElement("People", "口水都快")
                );
            doc6.Save(@"C:\Users\Alan\Desktop\AvalonSolution\ConsoleTesrt\LINQTest\XMLData2.xml");
            Console.WriteLine("添加了一个文档类型的XML创建成功");
            //todo:给你一个字符串，变成一个XMl对象
            string xmlStr = "<Product ID=\"2\"><ID type=\"int\">2<!--编号--></ID><ProductCode type=\"nvarchar(50)\">WP7CXSJ<!--产品编号--></ProductCode>"
  + "<ProductName type=\"nvarchar(50)\">Windows Phone7 程序设计</ProductName>"
     + " <ProductUnitPrice type=\"decimal(18,2)\">99.00<!--产品单价--></ProductUnitPrice>"
      + "<ProductTypeID type=\"smallint\" ForeignTable=\"ProductType\" ForeignTableColumn=\"ID\">2<!--产品类型--></ProductTypeID>"
      + "<ProductDescription type=\"nvarchar(200)\">wp7开发必备<!--产品描述--></ProductDescription>"
    + "</Product>";
            XElement txe = XElement.Parse(xmlStr);
            txe.Save(@"C:\Users\Alan\Desktop\AvalonSolution\ConsoleTesrt\LINQTest\XMLData25.xml");
        }
        public void CreateXML()
        {
            #region 创建一个XML文件夹
            //string dir = Environment.CurrentDirectory + @"/XML";
            //if (!Directory.Exists(dir))
            //{
            //    Directory.CreateDirectory(dir);
            //}
            #endregion
            string filePath1 = @"C:\Users\Alan\Desktop\AvalonSolution\ConsoleTesrt\LINQTest\XMLData.xml";
            #region 创建一个xml
            //创建一个xml文档
            XDocument doc1 = new XDocument(
                //创建一个声明
                   new XDeclaration("1.0", "utf-8", "yes"),
                   new XElement("Products",
                                   new XAttribute("KeyName", "ID"),
                                   new XAttribute("Identity", "true"),
                                   new XAttribute("IdentitySeed", "1"),
                                   new XAttribute("IdentityIncrement", "1"), new XComment("ID是产品表中的主键"),
                                   new XElement("Product", new XAttribute("ID", "1"),
                                          new XElement("ID", "1", new XComment("编号"), new XAttribute("type", "int")),
                                          new XElement("ProductCode", "XYBCNSZYXMN", new XComment("产品编号"), new XAttribute("type", "nvarchar(50)")),
                                          new XElement("ProductName", "相宜本草男士专用洗面奶", new XComment("产品名称"), new XAttribute("type", "nvarchar(50)")),
                                          new XElement("ProductUnitPrice", "39.90", new XComment("产品单价"), new XAttribute("type", "decimal(18,2)")),
                                          new XElement("ProductTypeID", "1", new XComment("产品类型"), new XAttribute("type", "smallint"),
                                                  new XAttribute("ForeignTable", "ProductType"),
                                                  new XAttribute("ForeignTableColumn", "ID")
                                          ),
                                          new XElement("ProductDescription", "祛痘效果很好", new XComment("产品描述"), new XAttribute("type", "nvarchar(200)"))
                            )
                       )
                );
            doc1.Save(filePath1);
            Console.WriteLine("创建成功");
            #endregion
        }
    }
}
